#pragma once

#include <d3d9.h>
#include <d3dx9.h>

#include "Singleton.h"
#include "Val3DRenderer.h"

class CameraManager;
class CLight;
class FontManager;

class RenderFacade : public Singleton<RenderFacade>
{
	LPDIRECT3D9			m_lpD3D9;
	LPDIRECT3DDEVICE9	m_lpd3dDevice;

	UINT	m_uClientWidth;
	UINT	m_uClientHeight;
	BOOL	m_bIsWindowed;

public:
	BOOL Init( HWND, UINT, UINT );
	void UnInit();

	LPDIRECT3D9	GetD3D();
	LPDIRECT3DDEVICE9 GetDxDevice();

	HRESULT	BeginDefaultRender();
	HRESULT	EndDefaultRender();
	HRESULT	Present( CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion );
	HRESULT Clear( DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil );

	HRESULT CreateTexture( UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle );
	HRESULT CreateVertexBuffer( UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle );
	HRESULT CreateIndexBuffer( UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle );

	HRESULT SetFVF( DWORD fvf );
	HRESULT GetFVF( DWORD* pfvf );
	HRESULT	SetTexture( DWORD Sampler, IDirect3DBaseTexture9 * pTexture );
	HRESULT GetTexture( DWORD Stage, IDirect3DBaseTexture9 ** ppTexture );
	HRESULT SetTextureStageState( DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value );
	HRESULT GetTextureStageState( DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD * pValue );
	HRESULT SetRenderState( D3DRENDERSTATETYPE State, DWORD Value );
	HRESULT GetRenderState( D3DRENDERSTATETYPE State, DWORD * pValue );
	HRESULT SetSamplerState( DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value );
	HRESULT GetSamplerState( DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* pValue );
	HRESULT SetTransform( D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix );
	HRESULT GetTransform( D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix );
	HRESULT SetStreamSource( UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride );
	HRESULT GetStreamSource( UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* pOffsetInBytes, UINT* pStride );
	HRESULT SetIndices( IDirect3DIndexBuffer9* pIndexData );
	HRESULT GetIndices( IDirect3DIndexBuffer9** pIndexData );
	HRESULT SetViewport( CONST D3DVIEWPORT9* pViewport );
	HRESULT GetViewport( D3DVIEWPORT9 * pViewport );
	HRESULT SetMaterial( CONST D3DMATERIAL9 * pMaterial );
	HRESULT GetMaterial( D3DMATERIAL9 * pMaterial );
	HRESULT SetLight( const DWORD& uIndex, const CLight* pLight );
	HRESULT GetLight( const DWORD& uIndex, CLight* pLight );
	HRESULT LightEnable( const DWORD& LightIndex, const BOOL& bEnable );

	HRESULT DrawPrimitive( D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT TriangleCount );
	HRESULT DrawIndexedPrimitive( D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT TriangleCount );
	HRESULT DrawPrimitiveUP( D3DPRIMITIVETYPE PrimitiveType, UINT TriangleCount, CONST void* pVertexArray, UINT VertexArraySize );

	HRESULT DXCreateTexture( UINT Width, UINT Height, UINT MipLevels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, LPDIRECT3DTEXTURE9* ppTexture );
	HRESULT DXCreateTextureFromFile( LPCTSTR pSrcFile, LPDIRECT3DTEXTURE9 * ppTexture );
	HRESULT DXCreateFont( INT Height, UINT Width, UINT Weight, UINT MipLevels, BOOL Italic, DWORD CharSet, DWORD OutputPrecision, DWORD Quality, DWORD PitchAndFamily, LPCTSTR pFacename, LPD3DXFONT* ppFont );
	HRESULT DXCreateFontIndirect( CONST D3DXFONT_DESC* pDesc, LPD3DXFONT* ppFont );

private:
	BOOL	InitD3DDisplayMode( D3DPRESENT_PARAMETERS& d3dpp );

public:
	RenderFacade(void);
	~RenderFacade(void);

public:
	Val3DRenderer * Get3DRenderer()		{ return m_pVal3DRenderer; }
	CameraManager *	GetCameraManager()	{ return m_pCameraManager; }
	FontManager *	GetFontManager()	{ return m_pFontManager; }

private:
	Val3DRenderer * m_pVal3DRenderer;
	CameraManager *	m_pCameraManager;
	FontManager *	m_pFontManager;
};
